// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`ArityError.react.js 1`] = `
/**
 * @providesModule ArityError.react
 */
var React = require('react');
var AudienceInsightsContainer = React.createClass({
  renderComponent(AudienceInsights: ReactClass<*>) {
    return <AudienceInsights />;
  },
});

module.exports = AudienceInsightsContainer;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/**
 * @providesModule ArityError.react
 */
var React = require("react");
var AudienceInsightsContainer = React.createClass({
  renderComponent(AudienceInsights: ReactClass<*>) {
    return <AudienceInsights />;
  }
});

module.exports = AudienceInsightsContainer;

`;

exports[`create_class.js 1`] = `
import React from "react";

const A = React.createClass({
  mixins: [{ propTypes: { foo: React.PropTypes.string.isRequired } }],
  propTypes: { bar: React.PropTypes.number.isRequired },
  m() {
    (this.props.foo: empty); // error: string ~> empty
    (this.props.bar: empty); // error: number ~> empty
  }
});

const B = React.createClass({
  p: "",
  m() {
    this.p = 0; // error: number ~> string
  },
  mm() {
    this.m.apply(null); // OK: this.m is autobound, so \`this.p\` will always be found
  }
});

const C = React.createClass({
  getInitialState(): Object {
    return { foo: 0 };
  },
  m() {
    this.state.foo; // OK: state is unknown
  }
});

const D = React.createClass({
  mixins: [{
    getInitialState(): Object {
      return { foo: 0 };
    },
  }],
  getInitialState() {
    return { bar: 0 };
  },
  m() {
    this.state.foo; // OK: state is unknown (due to unknown mixin)
  }
});

const E = React.createClass({
  foo: 0,
  m() {
    (this.foo: string); // error: number ~> string
  },
  mm() {
    var props: { m(): void } = { m: this.m };
    props.m(); // OK: this.m is autobound, so \`this.foo\` will always be found
  }
});

const F = React.createClass({
  getInitialState(): { [string]: mixed } {
    return { foo: 0 };
  },
  m() {
    this.state.foo;
    this.state.bar;
  },
});

const G = React.createClass({
  mixins: [],
  autobind: true,
  statics: {},
  m() {
    (this.mixins: mixed); // error: property \`mixins\` not found
    (this.autobind: mixed); // error: property \`autobind\` not found
    (this.statics: mixed); // error: property \`statics\` not found
  },
});

const H = React.createClass({
  statics: { q: 0 },
  getDefaultProps() {
    (this.q: empty); // error: number ~> empty
    return {};
  },
});

const I = React.createClass({
  propTypes: ({}: {[string]: any}),
  m() {
    (this.props.foo: empty); // OK
  }
});

const J = React.createClass({
  mixins: [{
    getInitialState() {
      return this.constructor.calculateState();
    },
  }],
  statics: {
    calculateState() {
      return { foo: 0 };
    },
  },
  m() {
    (this.state.foo: empty); // number ~> empty
  },
});

const K = React.createClass({
  propTypes: {
    foo: React.PropTypes.string.isRequired,
  },
  getInitialState() {
    this.mm(); // cause error in mm below
    return this.props;
  },
  m() {
    (this.props.foo: empty); // string ~> empty
    (this.state.foo: empty); // string ~> empty
  },
  mm() {
    this.state.foo; // error: property fo not found (called by getInitialState)
  }
});

const L = React.createClass({
  propTypes: {
    foo: React.PropTypes.string.isRequired,
  },
  getInitialState() {
    return { bar: 0 };
  },
  componentWillMount() {
    (this.props.foo: empty); // string ~> empty
    return 0; // number ~> void
  },
  componentDidMount() {
    (this.props.foo: empty); // string ~> empty
    return 0; // number ~> void
  },
  componentWillReceiveProps(nextProps) {
    (this.props.foo: empty); // string ~> empty
    (nextProps.foo: empty); // string ~> empty
    return 0; // number ~> void
  },
  shouldComponentUpdate(nextProps, nextState) {
    (this.props.foo: empty); // string ~> empty
    (this.state.bar: empty); // number ~> empty
    (nextProps.foo: empty); // string ~> empty
    (nextState.bar: empty); // number ~> empty
    return 0; // number ~> bool
  },
  componentWillUpdate(nextProps, nextState) {
    (this.props.foo: empty); // string ~> empty
    (this.state.bar: empty); // number ~> empty
    (nextProps.foo: empty); // string ~> empty
    (nextState.bar: empty); // number ~> empty
    return 0; // number ~> void
  },
  componentDidUpdate(nextProps, nextState) {
    (this.props.foo: empty); // string ~> empty
    (this.state.bar: empty); // number ~> empty
    (nextProps.foo: empty); // string ~> empty
    (nextState.bar: empty); // number ~> empty
    return 0; // number ~> void
  },
  componentWillUnmount() {
    (this.props.foo: empty); // string ~> empty
    (this.state.bar: empty); // number ~> empty
    return 0; // number ~> void
  },
});

React.createClass({}); // error: spec must be [x] exact and [ ] sealed
React.createClass(({}: {})); // error: spec must be [ ] exact and [x] sealed
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
import React from "react";

const A = React.createClass({
  mixins: [{ propTypes: { foo: React.PropTypes.string.isRequired } }],
  propTypes: { bar: React.PropTypes.number.isRequired },
  m() {
    (this.props.foo: empty); // error: string ~> empty
    (this.props.bar: empty); // error: number ~> empty
  }
});

const B = React.createClass({
  p: "",
  m() {
    this.p = 0; // error: number ~> string
  },
  mm() {
    this.m.apply(null); // OK: this.m is autobound, so \`this.p\` will always be found
  }
});

const C = React.createClass({
  getInitialState(): Object {
    return { foo: 0 };
  },
  m() {
    this.state.foo; // OK: state is unknown
  }
});

const D = React.createClass({
  mixins: [
    {
      getInitialState(): Object {
        return { foo: 0 };
      }
    }
  ],
  getInitialState() {
    return { bar: 0 };
  },
  m() {
    this.state.foo; // OK: state is unknown (due to unknown mixin)
  }
});

const E = React.createClass({
  foo: 0,
  m() {
    (this.foo: string); // error: number ~> string
  },
  mm() {
    var props: { m(): void } = { m: this.m };
    props.m(); // OK: this.m is autobound, so \`this.foo\` will always be found
  }
});

const F = React.createClass({
  getInitialState(): { [string]: mixed } {
    return { foo: 0 };
  },
  m() {
    this.state.foo;
    this.state.bar;
  }
});

const G = React.createClass({
  mixins: [],
  autobind: true,
  statics: {},
  m() {
    (this.mixins: mixed); // error: property \`mixins\` not found
    (this.autobind: mixed); // error: property \`autobind\` not found
    (this.statics: mixed); // error: property \`statics\` not found
  }
});

const H = React.createClass({
  statics: { q: 0 },
  getDefaultProps() {
    (this.q: empty); // error: number ~> empty
    return {};
  }
});

const I = React.createClass({
  propTypes: ({}: { [string]: any }),
  m() {
    (this.props.foo: empty); // OK
  }
});

const J = React.createClass({
  mixins: [
    {
      getInitialState() {
        return this.constructor.calculateState();
      }
    }
  ],
  statics: {
    calculateState() {
      return { foo: 0 };
    }
  },
  m() {
    (this.state.foo: empty); // number ~> empty
  }
});

const K = React.createClass({
  propTypes: {
    foo: React.PropTypes.string.isRequired
  },
  getInitialState() {
    this.mm(); // cause error in mm below
    return this.props;
  },
  m() {
    (this.props.foo: empty); // string ~> empty
    (this.state.foo: empty); // string ~> empty
  },
  mm() {
    this.state.foo; // error: property fo not found (called by getInitialState)
  }
});

const L = React.createClass({
  propTypes: {
    foo: React.PropTypes.string.isRequired
  },
  getInitialState() {
    return { bar: 0 };
  },
  componentWillMount() {
    (this.props.foo: empty); // string ~> empty
    return 0; // number ~> void
  },
  componentDidMount() {
    (this.props.foo: empty); // string ~> empty
    return 0; // number ~> void
  },
  componentWillReceiveProps(nextProps) {
    (this.props.foo: empty); // string ~> empty
    (nextProps.foo: empty); // string ~> empty
    return 0; // number ~> void
  },
  shouldComponentUpdate(nextProps, nextState) {
    (this.props.foo: empty); // string ~> empty
    (this.state.bar: empty); // number ~> empty
    (nextProps.foo: empty); // string ~> empty
    (nextState.bar: empty); // number ~> empty
    return 0; // number ~> bool
  },
  componentWillUpdate(nextProps, nextState) {
    (this.props.foo: empty); // string ~> empty
    (this.state.bar: empty); // number ~> empty
    (nextProps.foo: empty); // string ~> empty
    (nextState.bar: empty); // number ~> empty
    return 0; // number ~> void
  },
  componentDidUpdate(nextProps, nextState) {
    (this.props.foo: empty); // string ~> empty
    (this.state.bar: empty); // number ~> empty
    (nextProps.foo: empty); // string ~> empty
    (nextState.bar: empty); // number ~> empty
    return 0; // number ~> void
  },
  componentWillUnmount() {
    (this.props.foo: empty); // string ~> empty
    (this.state.bar: empty); // number ~> empty
    return 0; // number ~> void
  }
});

React.createClass({}); // error: spec must be [x] exact and [ ] sealed
React.createClass(({}: {})); // error: spec must be [ ] exact and [x] sealed

`;

exports[`create_class_initial_state_sealed.js 1`] = `
import React from "react";

// initial state = None
React.createClass({
  f() {
    this.setState({ q: 0 });
  },
  g() {
    (this.state.q: empty); // number ~> empty
  }
});

// initial state = Some (exact & sealed) [lit]
React.createClass({
  getInitialState() {
    return { p: 0 };
  },
  f() {
    this.setState({ q: 0 });
  },
  g() {
    (this.state.q: empty); // number ~> empty
  }
});

// initial state = Some (exact & sealed) [annot]
React.createClass({
  getInitialState(): {| p: number |} {
    return { p: 0 };
  },
  f() {
    this.setState({ q: 0 });
  },
  g() {
    (this.state.q: empty); // number ~> empty
  }
});

// initial state = Some (inexact & sealed) [annot]
React.createClass({
  getInitialState(): { p: number } {
    return { p: 0 };
  },
  f() {
    this.setState({ q: 0 }); // property \`q\` not found
  },
  g() {
    (this.state.q: empty); // property \`q\` not found
  }
});

// mixins = (exact & sealed) + (exact & sealed)
React.createClass({
  mixins: [{
    getInitialState() {
      return { foo: 0 };
    },
  }],
  getInitialState() {
    return { bar: 0 };
  },
  f() {
    this.setState({ baz: 0 });
  },
  g() {
    (this.state.baz: empty); // number ~> empty
  }
});

// mixins = (exact & sealed) + (inexact & sealed)
React.createClass({
  mixins: [{
    getInitialState(): { foo: number } {
      return { foo: 0 };
    },
  }],
  getInitialState() {
    return { bar: 0 };
  },
  f() {
    this.setState({ baz: 0 }); // property \`baz\`  not found
  },
  g() {
    (this.state.baz: empty); // property \`baz\` not found
  }
});
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
import React from "react";

// initial state = None
React.createClass({
  f() {
    this.setState({ q: 0 });
  },
  g() {
    (this.state.q: empty); // number ~> empty
  }
});

// initial state = Some (exact & sealed) [lit]
React.createClass({
  getInitialState() {
    return { p: 0 };
  },
  f() {
    this.setState({ q: 0 });
  },
  g() {
    (this.state.q: empty); // number ~> empty
  }
});

// initial state = Some (exact & sealed) [annot]
React.createClass({
  getInitialState(): {| p: number |} {
    return { p: 0 };
  },
  f() {
    this.setState({ q: 0 });
  },
  g() {
    (this.state.q: empty); // number ~> empty
  }
});

// initial state = Some (inexact & sealed) [annot]
React.createClass({
  getInitialState(): { p: number } {
    return { p: 0 };
  },
  f() {
    this.setState({ q: 0 }); // property \`q\` not found
  },
  g() {
    (this.state.q: empty); // property \`q\` not found
  }
});

// mixins = (exact & sealed) + (exact & sealed)
React.createClass({
  mixins: [
    {
      getInitialState() {
        return { foo: 0 };
      }
    }
  ],
  getInitialState() {
    return { bar: 0 };
  },
  f() {
    this.setState({ baz: 0 });
  },
  g() {
    (this.state.baz: empty); // number ~> empty
  }
});

// mixins = (exact & sealed) + (inexact & sealed)
React.createClass({
  mixins: [
    {
      getInitialState(): { foo: number } {
        return { foo: 0 };
      }
    }
  ],
  getInitialState() {
    return { bar: 0 };
  },
  f() {
    this.setState({ baz: 0 }); // property \`baz\`  not found
  },
  g() {
    (this.state.baz: empty); // property \`baz\` not found
  }
});

`;

exports[`create_class_statics_sealed.js 1`] = `
import React from "react";

// statics = None
const A = React.createClass({ p: 0 });
(A.bar: empty); // number ~> empty (inflow below)
A.bar = 0;

// statics = Some (exact & sealed) [lit]
const B = React.createClass({
  statics: { foo: 0 },
});
(B.foo: empty); // number ~> empty
(B.bar: empty); // number ~> empty (inflow below)
B.bar = 0;

// statics = Some (exact & sealed) [annot]
const C = React.createClass({
  statics: ({ foo: 0 }: {| foo: number |}),
});
(C.foo: empty); // number ~> empty
(C.bar: empty); // number ~> empty (inflow below)
C.bar = 0;

// statics = Some (inexact & sealed) [annot]
const D = React.createClass({
  statics: ({ foo: 0 }: { foo: number }),
});
(D.foo: empty); // number ~> empty
(D.bar: empty); // property \`bar\` not found
D.bar = 0; // property \`bar\` not found

// mixins: (exact & sealed) + (exact & sealed)
const E = React.createClass({
  mixins: [{
    statics: { foo: 0 },
  }],
  statics: { bar: 0 },
});
(E.foo: empty); // number ~> empty
(E.bar: empty); // number ~> empty
(E.baz: empty); // number ~> empty (inflow below)
E.baz = 0;

// mixins: (exact & sealed) + (inexact & sealed)
const F = React.createClass({
  mixins: [{
    statics: ({ foo: 0 }: { foo: number }),
  }],
  statics: { bar: 0 },
});
(F.foo: empty); // number ~> empty
(F.bar: empty); // number ~> empty
(F.baz: empty); // number ~> empty (inflow below)
F.baz = 0;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
import React from "react";

// statics = None
const A = React.createClass({ p: 0 });
(A.bar: empty); // number ~> empty (inflow below)
A.bar = 0;

// statics = Some (exact & sealed) [lit]
const B = React.createClass({
  statics: { foo: 0 }
});
(B.foo: empty); // number ~> empty
(B.bar: empty); // number ~> empty (inflow below)
B.bar = 0;

// statics = Some (exact & sealed) [annot]
const C = React.createClass({
  statics: ({ foo: 0 }: {| foo: number |})
});
(C.foo: empty); // number ~> empty
(C.bar: empty); // number ~> empty (inflow below)
C.bar = 0;

// statics = Some (inexact & sealed) [annot]
const D = React.createClass({
  statics: ({ foo: 0 }: { foo: number })
});
(D.foo: empty); // number ~> empty
(D.bar: empty); // property \`bar\` not found
D.bar = 0; // property \`bar\` not found

// mixins: (exact & sealed) + (exact & sealed)
const E = React.createClass({
  mixins: [
    {
      statics: { foo: 0 }
    }
  ],
  statics: { bar: 0 }
});
(E.foo: empty); // number ~> empty
(E.bar: empty); // number ~> empty
(E.baz: empty); // number ~> empty (inflow below)
E.baz = 0;

// mixins: (exact & sealed) + (inexact & sealed)
const F = React.createClass({
  mixins: [
    {
      statics: ({ foo: 0 }: { foo: number })
    }
  ],
  statics: { bar: 0 }
});
(F.foo: empty); // number ~> empty
(F.bar: empty); // number ~> empty
(F.baz: empty); // number ~> empty (inflow below)
F.baz = 0;

`;

exports[`createElement_string.js 1`] = `
// @flow
import React from 'react';

class Bar extends React.Component {}

class Foo extends React.Component {
  render() {
    const Cmp = Math.random() < 0.5 ? 'div' : Bar;
    return (<Cmp/>);
  }
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @flow
import React from "react";

class Bar extends React.Component {}

class Foo extends React.Component {
  render() {
    const Cmp = Math.random() < 0.5 ? "div" : Bar;
    return <Cmp />;
  }
}

`;

exports[`createElementRequiredProp_string.js 1`] = `
// @flow
import React from 'react';

class Bar extends React.Component {
  props: {
    test: number,
  };
  render() {
    return (
      <div>
        {this.props.test}
      </div>
    )
  }
}

class Foo extends React.Component {
  render() {
    const Cmp = Math.random() < 0.5 ? 'div' : Bar;
    return (<Cmp/>);
  }
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @flow
import React from "react";

class Bar extends React.Component {
  props: {
    test: number
  };
  render() {
    return <div>{this.props.test}</div>;
  }
}

class Foo extends React.Component {
  render() {
    const Cmp = Math.random() < 0.5 ? "div" : Bar;
    return <Cmp />;
  }
}

`;

exports[`import_react.js 1`] = `
/* @flow */

import react from "react";
import {Component} from "react";

var a: Component<*,*,*> = new react.Component();
var b: number = new react.Component(); // Error: ReactComponent ~> number
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @flow */

import react from "react";
import { Component } from "react";

var a: Component<*, *, *> = new react.Component();
var b: number = new react.Component(); // Error: ReactComponent ~> number

`;

exports[`jsx_spread.js 1`] = `
/* @flow */

var React = require('react');
var Foo = React.createClass({
  propTypes: {
    bar: React.PropTypes.string.isRequired,
  },
});

var props = {bar: 42};
var blah = <Foo {...props} />; // error bar, number given string expected
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @flow */

var React = require("react");
var Foo = React.createClass({
  propTypes: {
    bar: React.PropTypes.string.isRequired
  }
});

var props = { bar: 42 };
var blah = <Foo {...props} />; // error bar, number given string expected

`;

exports[`proptype_any.js 1`] = `
const React = require("react");

var AnyExample = React.createClass({
  propTypes: {
    foo: (0: any), // OK
  },
});

(<AnyExample />); // OK
(<AnyExample foo={(0: mixed)} />); // OK

var AnyFunExample = React.createClass({
  propTypes: {
    foo: (() => {}: Function), // OK
  },
});

(<AnyFunExample />); // OK
(<AnyFunExample foo={(0: mixed)} />); // OK
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
const React = require("react");

var AnyExample = React.createClass({
  propTypes: {
    foo: (0: any) // OK
  }
});

<AnyExample />; // OK
<AnyExample foo={(0: mixed)} />; // OK

var AnyFunExample = React.createClass({
  propTypes: {
    foo: (() => {}: Function) // OK
  }
});

<AnyFunExample />; // OK
<AnyFunExample foo={(0: mixed)} />; // OK

`;

exports[`proptype_arrayOf.js 1`] = `
/* @flow */

var React = require('react');
var Example = React.createClass({
  propTypes: {
    arr: React.PropTypes.arrayOf(React.PropTypes.number).isRequired,
  },
});

var ok_empty = <Example arr={[]} />
var ok_numbers = <Example arr={[1, 2]} />

var fail_missing = <Example />
var fail_not_array = <Example arr={2} />
var fail_mistyped_elems = <Example arr={[1, "foo"]} />

/* Since the \`number\` proptype argument is not required, React will actually
   allow \`null\` and \`undefined\` elements in the \`arr\` prop, but Flow has
   currently ignores the innter prop type's required flag. */
var todo_required = <Example arr={[null]} />

var OptionalExample = React.createClass({
  propTypes: {
    arr: React.PropTypes.arrayOf(React.PropTypes.number),
  }
});

(<OptionalExample />); // OK
(<OptionalExample arr={[0]} />); // OK
(<OptionalExample arr={[""]} />); // error: string ~> number

var AnyExample = React.createClass({
  propTypes: {
    arr: React.PropTypes.arrayOf((0:any)), // OK
  },
});

(<AnyExample arr={0} />); // error: still needs to be an array
(<AnyExample arr={[0]} />); // OK

var InvalidExample = React.createClass({
  propTypes: {
    arr: React.PropTypes.arrayOf(0), // error: number not a prop type
  },
});
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @flow */

var React = require("react");
var Example = React.createClass({
  propTypes: {
    arr: React.PropTypes.arrayOf(React.PropTypes.number).isRequired
  }
});

var ok_empty = <Example arr={[]} />;
var ok_numbers = <Example arr={[1, 2]} />;

var fail_missing = <Example />;
var fail_not_array = <Example arr={2} />;
var fail_mistyped_elems = <Example arr={[1, "foo"]} />;

/* Since the \`number\` proptype argument is not required, React will actually
   allow \`null\` and \`undefined\` elements in the \`arr\` prop, but Flow has
   currently ignores the innter prop type's required flag. */
var todo_required = <Example arr={[null]} />;

var OptionalExample = React.createClass({
  propTypes: {
    arr: React.PropTypes.arrayOf(React.PropTypes.number)
  }
});

<OptionalExample />; // OK
<OptionalExample arr={[0]} />; // OK
<OptionalExample arr={[""]} />; // error: string ~> number

var AnyExample = React.createClass({
  propTypes: {
    arr: React.PropTypes.arrayOf((0: any)) // OK
  }
});

<AnyExample arr={0} />; // error: still needs to be an array
<AnyExample arr={[0]} />; // OK

var InvalidExample = React.createClass({
  propTypes: {
    arr: React.PropTypes.arrayOf(0) // error: number not a prop type
  }
});

`;

exports[`proptype_custom_validator.js 1`] = `
const React = require("react");

// Custom validator must match \`ReactPropsCheckType\`
var Example = React.createClass({
  propTypes: {
    foo(props, propName, componentName, href) {
      (props: empty); // ok: props is \`any\`
      (propName: empty); // error: propName is a string
      (componentName: empty); // error: componentName is a string
      (href: empty); // error: href is an optional string
      return (0: mixed); // error: should return ?Error
    },
  }
});

// Inferred prop type is optional \`any\`
(<Example />);
(<Example foo={(0: mixed)} />);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
const React = require("react");

// Custom validator must match \`ReactPropsCheckType\`
var Example = React.createClass({
  propTypes: {
    foo(props, propName, componentName, href) {
      (props: empty); // ok: props is \`any\`
      (propName: empty); // error: propName is a string
      (componentName: empty); // error: componentName is a string
      (href: empty); // error: href is an optional string
      return (0: mixed); // error: should return ?Error
    }
  }
});

// Inferred prop type is optional \`any\`
<Example />;
<Example foo={(0: mixed)} />;

`;

exports[`proptype_func.js 1`] = `
/* @flow */

var React = require('react');
var Example = React.createClass({
  propTypes: {
    func: React.PropTypes.func.isRequired
  },
});

var ok_void = <Example func={() => {}} />;
var ok_args = <Example func={(x) => {}} />;
var ok_retval = <Example func={() => 1} />

var fail_mistyped = <Example func={2} />
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @flow */

var React = require("react");
var Example = React.createClass({
  propTypes: {
    func: React.PropTypes.func.isRequired
  }
});

var ok_void = <Example func={() => {}} />;
var ok_args = <Example func={x => {}} />;
var ok_retval = <Example func={() => 1} />;

var fail_mistyped = <Example func={2} />;

`;

exports[`proptype_incompatible.js 1`] = `
const React = require("react");

var Example = React.createClass({
  propTypes: {
    foo: 0, // error: \`0\` is not a prop type
  },
});

(<Example />); // OK: don't cascade errors
(<Example foo={(0:mixed)} />); // OK: don't cascade errors
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
const React = require("react");

var Example = React.createClass({
  propTypes: {
    foo: 0 // error: \`0\` is not a prop type
  }
});

<Example />; // OK: don't cascade errors
<Example foo={(0: mixed)} />; // OK: don't cascade errors

`;

exports[`proptype_instanceOf.js 1`] = `
/* @flow */

class A {}
class B extends A {}
class C extends B {}

var React = require('react');
var Example = React.createClass({
  propTypes: {
    x: React.PropTypes.instanceOf(B),
  }
});

(<Example x={new A} />); // error: A ~> B
(<Example x={new B} />); // OK
(<Example x={new C} />); // OK (C ~> B)
(<Example x="wrong" />); // error: string ~> B

class Poly<T> {x:T}
var PolyExample = React.createClass({
  propTypes: {
    x: React.PropTypes.instanceOf(Poly).isRequired,
  },
  m() {
    (this.props.x.x: empty); // OK, T instantiated to \`any\`
  }
});

// Different instantiations don't interact
(<PolyExample x={(new Poly(): Poly<string>)} />); // OK
(<PolyExample x={(new Poly(): Poly<number>)} />); // OK

class PolyDefault<T=string> {x:T}
var PolyDefaultExample = React.createClass({
  propTypes: {
    x: React.PropTypes.instanceOf(PolyDefault).isRequired,
  },
  m() {
    (this.props.x.x: empty); // OK, T instantiated to \`any\`
  }
});
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @flow */

class A {}
class B extends A {}
class C extends B {}

var React = require("react");
var Example = React.createClass({
  propTypes: {
    x: React.PropTypes.instanceOf(B)
  }
});

<Example x={new A()} />; // error: A ~> B
<Example x={new B()} />; // OK
<Example x={new C()} />; // OK (C ~> B)
<Example x="wrong" />; // error: string ~> B

class Poly<T> {
  x: T;
}
var PolyExample = React.createClass({
  propTypes: {
    x: React.PropTypes.instanceOf(Poly).isRequired
  },
  m() {
    (this.props.x.x: empty); // OK, T instantiated to \`any\`
  }
});

// Different instantiations don't interact
<PolyExample x={(new Poly(): Poly<string>)} />; // OK
<PolyExample x={(new Poly(): Poly<number>)} />; // OK

class PolyDefault<T = string> {
  x: T;
}
var PolyDefaultExample = React.createClass({
  propTypes: {
    x: React.PropTypes.instanceOf(PolyDefault).isRequired
  },
  m() {
    (this.props.x.x: empty); // OK, T instantiated to \`any\`
  }
});

`;

exports[`proptype_missing.js 1`] = `
/* @flow */

/* If you create a react component with createClass() but don't specify the
 * propTypes, what should the type of props be?
 *
 * It used to be an empty object, but we didn't enforce that correctly, so
 * people could do whatever they wanted with this.props.
 *
 * As of 0.21.0 it started to be an error when people used this.props in a
 * strict equality situation. It was weird that this was only sometimes
 * enforced, so glevi changed this.props to be Object by default.
 *
 * We may change this back to the empty object at some point and fix the
 * situations where it didn't used to error
 */
var React = require('react');
var Foo = React.createClass({
  getID(): string {
    // So this would have been an error in 0.21.0 if we didn't make this.props
    // Object
    switch (this.props.name) {
      case 'a': return 'Bob';
      default: return 'Alice';
    }
  },

  render() {
    // But this never errored
    return <div id={this.props.name} />;
  }
});
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @flow */

/* If you create a react component with createClass() but don't specify the
 * propTypes, what should the type of props be?
 *
 * It used to be an empty object, but we didn't enforce that correctly, so
 * people could do whatever they wanted with this.props.
 *
 * As of 0.21.0 it started to be an error when people used this.props in a
 * strict equality situation. It was weird that this was only sometimes
 * enforced, so glevi changed this.props to be Object by default.
 *
 * We may change this back to the empty object at some point and fix the
 * situations where it didn't used to error
 */
var React = require("react");
var Foo = React.createClass({
  getID(): string {
    // So this would have been an error in 0.21.0 if we didn't make this.props
    // Object
    switch (this.props.name) {
      case "a":
        return "Bob";
      default:
        return "Alice";
    }
  },

  render() {
    // But this never errored
    return <div id={this.props.name} />;
  }
});

`;

exports[`proptype_object.js 1`] = `
/* @flow */

var React = require('react');
var Example = React.createClass({
  propTypes: {
    object: React.PropTypes.object.isRequired
  },
});

var ok_empty = <Example object={{}} />;
var ok_props = <Example object={{foo: "bar"}} />;

var fail_mistyped = <Example object={2} />
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @flow */

var React = require("react");
var Example = React.createClass({
  propTypes: {
    object: React.PropTypes.object.isRequired
  }
});

var ok_empty = <Example object={{}} />;
var ok_props = <Example object={{ foo: "bar" }} />;

var fail_mistyped = <Example object={2} />;

`;

exports[`proptype_objectOf.js 1`] = `
/* @flow */

var React = require('react');
var Example = React.createClass({
  propTypes: {
    obj: React.PropTypes.objectOf(React.PropTypes.number).isRequired
  },
});

var ok_empty = <Example obj={{}} />
var ok_numbers = <Example obj={{foo: 1, bar: 2}} />

var fail_missing = <Example />
var fail_not_object = <Example obj={2} />
var fail_mistyped_props = <Example obj={{foo: "foo"}} />

/* Since the \`number\` proptype argument is not required, React will actually
   allow \`null\` and \`undefined\` elements in the \`obj\` prop, but Flow has
   currently ignores the innter prop type's required flag. */
var todo_required = <Example obj={{p:null}} />

var OptionalExample = React.createClass({
  propTypes: {
    obj: React.PropTypes.objectOf(React.PropTypes.number),
  }
});

(<OptionalExample />); // OK
(<OptionalExample obj={{p:0}} />); // OK
(<OptionalExample obj={{p:""}} />); // error: string ~> number

var AnyExample = React.createClass({
  propTypes: {
    obj: React.PropTypes.objectOf((0:any)), // OK
  },
});

(<AnyExample obj={0} />); // error: still needs to be an object
(<AnyExample obj={{p:0}} />); // OK

var InvalidExample = React.createClass({
  propTypes: {
    obj: React.PropTypes.objectOf(0), // error: number not a prop type
  },
});
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @flow */

var React = require("react");
var Example = React.createClass({
  propTypes: {
    obj: React.PropTypes.objectOf(React.PropTypes.number).isRequired
  }
});

var ok_empty = <Example obj={{}} />;
var ok_numbers = <Example obj={{ foo: 1, bar: 2 }} />;

var fail_missing = <Example />;
var fail_not_object = <Example obj={2} />;
var fail_mistyped_props = <Example obj={{ foo: "foo" }} />;

/* Since the \`number\` proptype argument is not required, React will actually
   allow \`null\` and \`undefined\` elements in the \`obj\` prop, but Flow has
   currently ignores the innter prop type's required flag. */
var todo_required = <Example obj={{ p: null }} />;

var OptionalExample = React.createClass({
  propTypes: {
    obj: React.PropTypes.objectOf(React.PropTypes.number)
  }
});

<OptionalExample />; // OK
<OptionalExample obj={{ p: 0 }} />; // OK
<OptionalExample obj={{ p: "" }} />; // error: string ~> number

var AnyExample = React.createClass({
  propTypes: {
    obj: React.PropTypes.objectOf((0: any)) // OK
  }
});

<AnyExample obj={0} />; // error: still needs to be an object
<AnyExample obj={{ p: 0 }} />; // OK

var InvalidExample = React.createClass({
  propTypes: {
    obj: React.PropTypes.objectOf(0) // error: number not a prop type
  }
});

`;

exports[`proptype_oneOf.js 1`] = `
/* @flow */

var React = require('react');
var Example = React.createClass({
  propTypes: {
    str: React.PropTypes.oneOf(["foo", "bar"]),
    num: React.PropTypes.oneOf([0, 1, 2]),
    bool: React.PropTypes.oneOf([true]),
    mixed: React.PropTypes.oneOf(["foo", 0, true]),
  },
});

(<Example str="foo" />); // OK
(<Example str="baz" />); // error: 'baz' not in enum

(<Example num={0} />); // OK
(<Example num={3} />); // error: 3 not in enum

(<Example bool={true} />); // OK
(<Example bool={false} />); // error: false ~> true

(<Example mixed={"foo"} />); // OK
(<Example mixed={0} />); // OK
(<Example mixed={"baz"} />); // error: 'baz' not in enum

var RequiredExample = React.createClass({
  propTypes: {
    p: React.PropTypes.oneOf([]).isRequired,
  },
});

(<RequiredExample />); // error: \`p\` not found

var EmptyExample = React.createClass({
  propTypes: {
    nil: React.PropTypes.oneOf([]), // i.e., \`empty\`
  },
});

(<EmptyExample nil={0} />); // number ~> empty

var AnyArrayExample = React.createClass({
  propTypes: {
    any: React.PropTypes.oneOf((0:any)),
  },
});

(<AnyArrayExample any={0} />); // OK

var AnyElemExample = React.createClass({
  propTypes: {
    any: React.PropTypes.oneOf(["foo", (0:any)]),
  },
});

(<AnyElemExample any={0} />); // OK

var DynamicArrayExample = React.createClass({
  propTypes: {
    dyn: React.PropTypes.oneOf(([]: Array<string>)),
  },
});

(<DynamicArrayExample dyn={0} />); // OK

var DynamicElemExample = React.createClass({
  propTypes: {
    dyn: React.PropTypes.oneOf(["foo", ("": string)]),
  },
});

(<DynamicElemExample dyn={0} />); // OK

var InvalidArrayExample = React.createClass({
  propTypes: {
    p: React.PropTypes.oneOf(0), // error: expected array, got 0
  },
});

(<InvalidArrayExample p={0} />); // OK, don't cascade errors

var NonLiteralElemExample = React.createClass({
  propTypes: {
    p: React.PropTypes.oneOf([{}]), // OK: allow non-literals
  },
});
(<NonLiteralElemExample p={0} />); // OK, result is unknown/any
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @flow */

var React = require("react");
var Example = React.createClass({
  propTypes: {
    str: React.PropTypes.oneOf(["foo", "bar"]),
    num: React.PropTypes.oneOf([0, 1, 2]),
    bool: React.PropTypes.oneOf([true]),
    mixed: React.PropTypes.oneOf(["foo", 0, true])
  }
});

<Example str="foo" />; // OK
<Example str="baz" />; // error: 'baz' not in enum

<Example num={0} />; // OK
<Example num={3} />; // error: 3 not in enum

<Example bool={true} />; // OK
<Example bool={false} />; // error: false ~> true

<Example mixed={"foo"} />; // OK
<Example mixed={0} />; // OK
<Example mixed={"baz"} />; // error: 'baz' not in enum

var RequiredExample = React.createClass({
  propTypes: {
    p: React.PropTypes.oneOf([]).isRequired
  }
});

<RequiredExample />; // error: \`p\` not found

var EmptyExample = React.createClass({
  propTypes: {
    nil: React.PropTypes.oneOf([]) // i.e., \`empty\`
  }
});

<EmptyExample nil={0} />; // number ~> empty

var AnyArrayExample = React.createClass({
  propTypes: {
    any: React.PropTypes.oneOf((0: any))
  }
});

<AnyArrayExample any={0} />; // OK

var AnyElemExample = React.createClass({
  propTypes: {
    any: React.PropTypes.oneOf(["foo", (0: any)])
  }
});

<AnyElemExample any={0} />; // OK

var DynamicArrayExample = React.createClass({
  propTypes: {
    dyn: React.PropTypes.oneOf(([]: Array<string>))
  }
});

<DynamicArrayExample dyn={0} />; // OK

var DynamicElemExample = React.createClass({
  propTypes: {
    dyn: React.PropTypes.oneOf(["foo", ("": string)])
  }
});

<DynamicElemExample dyn={0} />; // OK

var InvalidArrayExample = React.createClass({
  propTypes: {
    p: React.PropTypes.oneOf(0) // error: expected array, got 0
  }
});

<InvalidArrayExample p={0} />; // OK, don't cascade errors

var NonLiteralElemExample = React.createClass({
  propTypes: {
    p: React.PropTypes.oneOf([{}]) // OK: allow non-literals
  }
});
<NonLiteralElemExample p={0} />; // OK, result is unknown/any

`;

exports[`proptype_oneOfType.js 1`] = `
/* @flow */

var React = require('react');
var Example = React.createClass({
  propTypes: {
    prop: React.PropTypes.oneOfType([
      React.PropTypes.string,
      React.PropTypes.number
    ]).isRequired
  },
  render() {
    if (typeof this.props.prop === "string") {
      return <div>{this.props.prop}</div>
    } else {
      return <div>{this.props.prop.toFixed(2)}</div>
    }
  }
});

var ok_number = <Example prop={42} />;
var ok_string = <Example prop="bar" />;

var fail_missing = <Example />;
var fail_bool = <Example prop={true} />;

/* Since the proptype arguments are not required, React will actually allow
   \`null\` and \`undefined\` elements in the \`prop\` prop, but Flow has currently
   ignores the innter prop types' required flags. */
var todo_required = <Example prop={null} />;

var OptionalExample = React.createClass({
  propTypes: {
    p: React.PropTypes.oneOfType([
      React.PropTypes.string,
    ]),
  },
});

(<OptionalExample />); // OK
(<OptionalExample p="" />); // OK
(<OptionalExample p={0} />); // error: number ~> string

var EmptyExample = React.createClass({
  propTypes: {
    nil: React.PropTypes.oneOfType([]), // i.e., \`empty\`
  },
});

(<EmptyExample nil={0} />); // number ~> empty

var AnyArrayExample = React.createClass({
  propTypes: {
    any: React.PropTypes.oneOfType((0:any)),
  },
});

(<AnyArrayExample any={0} />); // OK

var AnyElemExample = React.createClass({
  propTypes: {
    any: React.PropTypes.oneOfType([
      React.PropTypes.string,
      (0:any),
    ]),
  },
});

(<AnyElemExample any={0} />); // OK

var DynamicArrayExample = React.createClass({
  propTypes: {
    dyn: React.PropTypes.oneOfType(([]: Array<Function>)),
  },
});

(<DynamicArrayExample dyn={0} />); // OK

var DynamicElemExample = React.createClass({
  propTypes: {
    dyn: React.PropTypes.oneOfType([
      React.PropTypes.string,
      (() => {}: Function),
    ]),
  },
});

(<DynamicElemExample dyn={0} />); // OK

var InvalidArrayExample = React.createClass({
  propTypes: {
    p: React.PropTypes.oneOfType(0), // error: expected array, got 0
  },
});

(<InvalidArrayExample p={0} />); // OK, don't cascade errors

var InvalidElemExample = React.createClass({
  propTypes: {
    p: React.PropTypes.oneOfType([{}]), // error: expected prop type, got {}
  },
});

(<InvalidElemExample p={0} />); // OK, don't cascade errors
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @flow */

var React = require("react");
var Example = React.createClass({
  propTypes: {
    prop: React.PropTypes.oneOfType([
      React.PropTypes.string,
      React.PropTypes.number
    ]).isRequired
  },
  render() {
    if (typeof this.props.prop === "string") {
      return <div>{this.props.prop}</div>;
    } else {
      return <div>{this.props.prop.toFixed(2)}</div>;
    }
  }
});

var ok_number = <Example prop={42} />;
var ok_string = <Example prop="bar" />;

var fail_missing = <Example />;
var fail_bool = <Example prop={true} />;

/* Since the proptype arguments are not required, React will actually allow
   \`null\` and \`undefined\` elements in the \`prop\` prop, but Flow has currently
   ignores the innter prop types' required flags. */
var todo_required = <Example prop={null} />;

var OptionalExample = React.createClass({
  propTypes: {
    p: React.PropTypes.oneOfType([React.PropTypes.string])
  }
});

<OptionalExample />; // OK
<OptionalExample p="" />; // OK
<OptionalExample p={0} />; // error: number ~> string

var EmptyExample = React.createClass({
  propTypes: {
    nil: React.PropTypes.oneOfType([]) // i.e., \`empty\`
  }
});

<EmptyExample nil={0} />; // number ~> empty

var AnyArrayExample = React.createClass({
  propTypes: {
    any: React.PropTypes.oneOfType((0: any))
  }
});

<AnyArrayExample any={0} />; // OK

var AnyElemExample = React.createClass({
  propTypes: {
    any: React.PropTypes.oneOfType([React.PropTypes.string, (0: any)])
  }
});

<AnyElemExample any={0} />; // OK

var DynamicArrayExample = React.createClass({
  propTypes: {
    dyn: React.PropTypes.oneOfType(([]: Array<Function>))
  }
});

<DynamicArrayExample dyn={0} />; // OK

var DynamicElemExample = React.createClass({
  propTypes: {
    dyn: React.PropTypes.oneOfType([
      React.PropTypes.string,
      (() => {}: Function)
    ])
  }
});

<DynamicElemExample dyn={0} />; // OK

var InvalidArrayExample = React.createClass({
  propTypes: {
    p: React.PropTypes.oneOfType(0) // error: expected array, got 0
  }
});

<InvalidArrayExample p={0} />; // OK, don't cascade errors

var InvalidElemExample = React.createClass({
  propTypes: {
    p: React.PropTypes.oneOfType([{}]) // error: expected prop type, got {}
  }
});

<InvalidElemExample p={0} />; // OK, don't cascade errors

`;

exports[`proptype_shape.js 1`] = `
/* Shape should be a sealed, inexact object just like a type annotation. The
 * below component's \`foo\` property should be equivalent to \`{ bar: string }\`,
 * which would forbid reads/writes on an unknown \`baz\` property.
 *
 * If you see a single "number incompatible with string" error instead of two
 * separate "property \`baz\` not found" errors, this is broken and we are
 * treating the shape like an unsealed object and performing shadow read/writes.
 */

import React from "react";

React.createClass({
  propTypes: {
    foo: React.PropTypes.shape({
      bar: React.PropTypes.string.isRequired,
    }).isRequired,
  },

  f() {
    (this.props.foo.baz: string);
  },

  g() {
    this.props.foo.baz = 0;
  }
});

React.createClass({
  propTypes: {
    foo: React.PropTypes.shape(({}: {[string]: any})).isRequired,
  },
  f() {
    (this.props.foo.bar: empty); // OK
  },
});
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* Shape should be a sealed, inexact object just like a type annotation. The
 * below component's \`foo\` property should be equivalent to \`{ bar: string }\`,
 * which would forbid reads/writes on an unknown \`baz\` property.
 *
 * If you see a single "number incompatible with string" error instead of two
 * separate "property \`baz\` not found" errors, this is broken and we are
 * treating the shape like an unsealed object and performing shadow read/writes.
 */

import React from "react";

React.createClass({
  propTypes: {
    foo: React.PropTypes.shape({
      bar: React.PropTypes.string.isRequired
    }).isRequired
  },

  f() {
    (this.props.foo.baz: string);
  },

  g() {
    this.props.foo.baz = 0;
  }
});

React.createClass({
  propTypes: {
    foo: React.PropTypes.shape(({}: { [string]: any })).isRequired
  },
  f() {
    (this.props.foo.bar: empty); // OK
  }
});

`;

exports[`proptypes_builtins.js 1`] = `
import React from "react";

type NoFun = mixed => empty;

// error: mixed ~> ReactPropsCheckType
// error: ReactPropsChainableTypeChecker ~> empty
(React.PropTypes.arrayOf : NoFun);

// OK: mixed ~> any
// error: ReactPropsChainableTypeChecker ~> empty
(React.PropTypes.instanceOf : NoFun);

// error: mixed ~> ReactPropsCheckType
// error: ReactPropsChainableTypeChecker ~> empty
(React.PropTypes.objectOf : NoFun);

// error: mixed ~> Array<any>
// error: ReactPropsChainableTypeChecker ~> empty
(React.PropTypes.oneOf : NoFun);

// error: mixed ~> Array<ReactPropsCheckType>
// error: ReactPropsChainableTypeChecker ~> empty
(React.PropTypes.oneOfType : NoFun);

// error: mixed ~> object type
// error: ReactPropsChainableTypeChecker ~> empty
(React.PropTypes.shape : NoFun);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
import React from "react";

type NoFun = mixed => empty;

// error: mixed ~> ReactPropsCheckType
// error: ReactPropsChainableTypeChecker ~> empty
(React.PropTypes.arrayOf: NoFun);

// OK: mixed ~> any
// error: ReactPropsChainableTypeChecker ~> empty
(React.PropTypes.instanceOf: NoFun);

// error: mixed ~> ReactPropsCheckType
// error: ReactPropsChainableTypeChecker ~> empty
(React.PropTypes.objectOf: NoFun);

// error: mixed ~> Array<any>
// error: ReactPropsChainableTypeChecker ~> empty
(React.PropTypes.oneOf: NoFun);

// error: mixed ~> Array<ReactPropsCheckType>
// error: ReactPropsChainableTypeChecker ~> empty
(React.PropTypes.oneOfType: NoFun);

// error: mixed ~> object type
// error: ReactPropsChainableTypeChecker ~> empty
(React.PropTypes.shape: NoFun);

`;

exports[`proptypes_sealed.js 1`] = `
/* propTypes should be a sealed, inexact object just like a type annotation. The
 * below component's propTypes should be equivalent to \`{ bar: string }\`, which
 * would forbid reads/writes on an unknown \`baz\` property.
 *
 * If you see a single "number incompatible with string" error instead of two
 * separate "property \`baz\` not found" errors, this is broken and we are
 * treating propTypes like an unsealed object and performing shadow read/writes.
 */

import React from "react";

React.createClass({
  propTypes: {
    foo: React.PropTypes.string.isRequired,
  },

  f() {
    (this.props.baz: string);
  },

  g() {
    this.props.baz = 0;
  }
});
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* propTypes should be a sealed, inexact object just like a type annotation. The
 * below component's propTypes should be equivalent to \`{ bar: string }\`, which
 * would forbid reads/writes on an unknown \`baz\` property.
 *
 * If you see a single "number incompatible with string" error instead of two
 * separate "property \`baz\` not found" errors, this is broken and we are
 * treating propTypes like an unsealed object and performing shadow read/writes.
 */

import React from "react";

React.createClass({
  propTypes: {
    foo: React.PropTypes.string.isRequired
  },

  f() {
    (this.props.baz: string);
  },

  g() {
    this.props.baz = 0;
  }
});

`;
